use floating_ui_leptos::{use_floating, Placement, UseFloatingOptions, UseFloatingReturn};
use leptos::{prelude::*, tachys::renderer::dom::Element};
use leptos_node_ref::AnyNodeRef;
use leptos_use::on_click_outside;
use thaw::*;
use wasm_bindgen::JsCast;

#[component]
pub fn UserProfile() -> impl IntoView {
    view! {
        <Card class="w-[300px] h-[320px]">
            <CardHeader>
                <Body1>
                    <b>"Header"</b>
                    " 2022-02-22"
                </Body1>
                <CardHeaderDescription slot>
                    <Caption1>"Description"</Caption1>
                </CardHeaderDescription>
                <CardHeaderAction slot>
                    <Button
                        appearance=ButtonAppearance::Transparent
                        icon=icondata::AiMoreOutlined
                    />
                </CardHeaderAction>
            </CardHeader>
            <CardPreview>
                <img
                    src="https://s3.bmp.ovh/imgs/2021/10/2c3b013418d55659.jpg"
                    style="width: 100%"
                />
            </CardPreview>
            <CardFooter class="flex justify-center items-center">
                <Button>"Reply"</Button>
                <Button>"Share"</Button>
            </CardFooter>
        </Card>
    }
}

#[component]
pub fn UserAvatarMenu(expand: RwSignal<bool>) -> impl IntoView {
    let show_menu = RwSignal::new(false);
    let reference_ref = AnyNodeRef::new();
    let floating_ref = AnyNodeRef::new();
    let UseFloatingReturn {
        x,
        y,
        floating_styles,
        ..
    } = use_floating(
        reference_ref,
        floating_ref,
        UseFloatingOptions::default().placement(Placement::BottomStart.into()),
    );
    let change_show_menu = move |_e: _| {
        show_menu.set(!show_menu.get());
    };
    let avatar_menu_id = "user_avatar_menu_id";
    let user_profile_node = AnyNodeRef::new();
    let _ = on_click_outside(user_profile_node, move |event| {
        for item in event.composed_path() {
            if let Ok(element) = item.dyn_into::<Element>() {
                if element.id().eq(avatar_menu_id) {
                    return;
                }
            }
        }
        show_menu.set(false);
    });
    view! {
        {move || {
            if expand.get() {
                view! {
                    <div
                        on:click=change_show_menu
                        id=avatar_menu_id
                        node_ref=reference_ref
                        class="w-[100px] h-[40px] flex justify-center items-center"
                    >
                        <Space class="justify-center items-center">
                            <Avatar name="王二麻子" />
                            <span style="color: white;">"王二麻子"</span>
                        </Space>
                    </div>
                }
                    .into_any()
            } else {
                view! {
                    <div
                        on:click=change_show_menu
                        id=avatar_menu_id
                        node_ref=reference_ref
                        class="w-[40px] h-[40px] flex justify-center items-center"
                    >
                        <Avatar name="王二麻子" />
                    </div>
                }
                    .into_any()
            }
        }}
        <div
            node_ref=floating_ref
            class:hidden=move || !show_menu.get()
            style:position=move || floating_styles.get().style_position()
            style:top=move || format!("{}px", y.get() - 90f64)
            style:left=move || format!("{}px", x.get() + 28f64)
            style:transform=move || floating_styles.get().style_transform().unwrap_or_default()
            style:will-change=move || floating_styles.get().style_will_change().unwrap_or_default()
            style:z-index="1"
        >
            <div node_ref=user_profile_node>
                <UserProfile />
            </div>
        </div>
    }
}
